package com.ruoyi.bigscreen.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ruoyi.bigscreen.domain.*;
import com.ruoyi.bigscreen.mapper.*;
import com.ruoyi.bigscreen.repository.*;
import com.ruoyi.bigscreen.service.TmBigScreenService;
import org.apache.poi.ss.formula.functions.EDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.*;

/**
 * @author Ding
 * @date 2021/1/19
 */
@Service
public class TmBigScreenServiceImpl implements TmBigScreenService {

    private Logger logger = LoggerFactory.getLogger(TmBigScreenServiceImpl.class);

    @Autowired
    TmAssetsMapper tmAssetsMapper;

    @Autowired
    TmLoopholeMapper tmLoopholeMapper;

    @Autowired
    TmOrganizationMapper tmOrganizationMapper;

    @Autowired
    TmPersonnelMapper tmPersonnelMapper;

    @Autowired
    TmToolkitMapper tmToolkitMapper;

    @Autowired
    TmEdgeMapper tmEdgeMapper;

    @Autowired
    TmAssetsRepos tmAssetsRepos;

    @Autowired
    TmLoopholeRepos tmLoopholeRepos;

    @Autowired
    TmOrganizationRepos tmOrganizationRepos;

    @Autowired
    TmPersonnelRepos tmPersonnelRepos;

    @Autowired
    TmToolkitRepos tmToolkitRepos;

    @Autowired
    TmEdgeRepos tmEdgeRepos;



    @Override
    public void addTmAssets() {
        QueryWrapper<TmAssets> qw = new QueryWrapper<>();
        List<TmAssets> tmAssetsList = tmAssetsMapper.selectList(qw);
        tmAssetsRepos.saveAll(tmAssetsList);
    }

    @Override
    public void addTmLoophole() {
        QueryWrapper<TmLoophole> qw = new QueryWrapper<>();
        List<TmLoophole> tmLoopholeList = tmLoopholeMapper.selectList(qw);
        tmLoopholeRepos.saveAll(tmLoopholeList);
    }

    @Override
    public void addTmOrganization() {
        QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
        List<TmOrganization> tmOrganizations = tmOrganizationMapper.selectList(qw);
        tmOrganizationRepos.saveAll(tmOrganizations);
    }

    @Override
    public void addTmPersonnel() {
        QueryWrapper<TmPersonnel> qw = new QueryWrapper<>();
        List<TmPersonnel> tmPersonnelList = tmPersonnelMapper.selectList(qw);
        tmPersonnelRepos.saveAll(tmPersonnelList);
    }

    @Override
    public void addTmToolkit() {
        QueryWrapper<TmToolkit> qw = new QueryWrapper<>();
        List<TmToolkit> tmToolkitList = tmToolkitMapper.selectList(qw);
        tmToolkitRepos.saveAll(tmToolkitList);
    }

    @Override
    public void addTmEdge() {
        QueryWrapper<TmEdge> qw = new QueryWrapper<>();
        List<TmEdge> tmEdges = tmEdgeMapper.selectList(qw);
        tmEdgeRepos.saveAll(tmEdges);
    }

    /**
     * @description 组织机构图
     * @return jsonString
     */
    @Override
    public String  TmOrganizationToJson() {//组织机构图
        Map<String ,Object> map = new  HashMap<>();
        QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
        qw.select("org_camp");
        qw.groupBy("org_camp");
        List<TmOrganization> tmOrganizations = tmOrganizationMapper.selectList(qw);
        System.out.println(JSON.toJSONString(tmOrganizations));
        //[{"orgCamp":"CN"},{"orgCamp":"TW"}]
        ArrayList<String> OrgCamparr = new ArrayList<>();
        for (TmOrganization a :tmOrganizations){
            OrgCamparr.add(a.getOrgCamp());
        }
        map.put("collection",OrgCamparr);
        //根据国家分类来查
        for(String key :OrgCamparr){
            qw.clear();
            List<TmOrganization> orglist = new ArrayList<>();//国家下的list最后拼起来
            qw.eq("org_camp",key);//指定国家
            qw.eq("org_mierarchy","1");//层级
            tmOrganizations= tmOrganizationMapper.selectList(qw);
            map.put(key,tmOrganizations);//1
            getJson(key,qw,tmOrganizations,map);
        }
        System.out.println(JSON.toJSONString(map));
        return JSON.toJSONString(map);
    }


    /**
     * @description 组织机构图递归查询，按照层级和orgID
     * @param key
     * @param qw
     * @param tmOrganizations
     * @param map
     * @return jsonString
     */
    private Map<String ,Object> getJson(String key,QueryWrapper<TmOrganization> qw,List<TmOrganization> tmOrganizations,Map<String ,Object> map){
        for(TmOrganization organ:tmOrganizations){
            qw.clear();
            qw.eq("org_camp",key);
            qw.eq("org_mierarchy",String.valueOf(Integer.valueOf(organ.getOrgMierarchy())+1));//层级+1
            qw.eq("parent_id",organ.getOrgId());
            List<TmOrganization> list = tmOrganizationMapper.selectList(qw);
            map.put(organ.getId(),list);
            if (list.size()>0){
                getJson(key,qw,list,map);
            }
        }
        return map;
    }

    /**
     * @description 第二种组织机构图的json
     * @return jsonString
     */
    @Override
    public String TmOrganizationToJson1() {
        QueryWrapper<TmOrganization> orgQW = new QueryWrapper<>();
        QueryWrapper<TmEdge> edgeQW = new QueryWrapper<>();
        orgQW.select("org_camp");
        orgQW.groupBy("org_camp");
        Map<String ,Object> map = new  HashMap<>();
        List<TmOrganization> tmOrganizations = tmOrganizationMapper.selectList(orgQW);//国家的列
        List<TmEdge> edgeList = tmEdgeMapper.selectList(edgeQW);
        ArrayList<String> OrgCamparr = new ArrayList<>();
        for (TmOrganization a :tmOrganizations){//根据阵营分别装入MAP
            Map<String ,Object> campMap= new HashMap<>();
            OrgCamparr.add(a.getOrgCamp());
            orgQW.clear();
            orgQW.eq("org_camp",a.getOrgCamp());//指定国家
            tmOrganizationMapper.selectList(orgQW);
            tmOrganizations= tmOrganizationMapper.selectList(orgQW);
            campMap.put("nodes",tmOrganizations);
            map.put(a.getOrgCamp(),campMap);
        }
        OrgCamparr.remove("CN");
        OrgCamparr.add(0,"CN");
        map.put("ocgCamp",OrgCamparr);//[{"orgCamp":"CN"},{"orgCamp":"TW"}]
        map.put("collections",edgeList);
        //放入国家的东西
        System.out.println(JSON.toJSONString(map));
        return JSON.toJSONString(map);
    }

    /**
     * @description 根据阵营查询orgnationas
     * @param orgCamp
     * @return List<TmOrganization>
     */
    @Override
    public List<TmOrganization> getOrganizationsByOrgCamp(String orgCamp) {
        QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
        if (orgCamp.toUpperCase().equals("CN")){
            qw.eq("org_camp",orgCamp);
        }else {
            qw.ne("org_camp","CN");
        }
        List<TmOrganization> tmOrganizations = tmOrganizationMapper.selectList(qw);
        return tmOrganizations;
    }

    /**
     * @description 根据阵营查询toolkit
     * @param orgCamp
     * @return jsonString
     */
    @Override
    public String getToolkitsByOrgCamp(String orgCamp) {
        Map<String,Map> jsonMap = new HashMap<>();
        Map<String,Object> rankingMap = new HashMap<>();
        List<Map<String,String>> dataList = new ArrayList<>();
        QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
        QueryWrapper<TmToolkit> qw1 = new QueryWrapper<>();
        if (orgCamp.toUpperCase().equals("CN")){
            qw.eq("org_camp",orgCamp);
        }else {
            qw.ne("org_camp","CN");
        }
        List<TmOrganization> tmOrganizations = tmOrganizationMapper.selectList(qw);
        if (tmOrganizations.size()>0){
            for (TmOrganization t:tmOrganizations){
                qw1.clear();
                Map<String,String> dMap = new HashMap<>();
                qw1.eq("org_id",t.getId());
                Integer i = tmToolkitMapper.selectCount(qw1);
                if (i>0){
                    dMap.put("name",t.getOrgName()+"("+t.getOrgCamp()+")");
                    dMap.put("value",String.valueOf(i));
                    dataList.add(dMap);
                }
            }
        }
        rankingMap.put("data",dataList);
        rankingMap.put("carousel","single");
        rankingMap.put("unit","个");
        jsonMap.put("ranking",rankingMap);
        return JSON.toJSONString(jsonMap);
    }

    /**
     * 很简单的一个根据orgCamp查询LoopHole
     * @param orgCamp
     * @return List<TmLoophole>
     */
    @Override
    public List<TmLoophole> getLoopHoleByOrgCamp(String orgCamp){//
        QueryWrapper<TmLoophole> qw = new QueryWrapper<>();
        if (orgCamp.toUpperCase().equals("CN")){
            qw.eq("org_camp",orgCamp);
        }else {
            qw.ne("org_camp","CN");
        }
        List<TmLoophole> loopholes = tmLoopholeMapper.selectList(qw);
        return loopholes;
    }

    /**
     * @description 机构/我方机构总数
     * @param orgCamp
     * @return
     */
    @Override
    public String orgPercent(String orgCamp) {
        QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
        if (orgCamp.toUpperCase().equals("CN")){
            qw.eq("org_camp",orgCamp);
        }else {
            qw.ne("org_camp","CN");
        }
        List<TmOrganization> tmOrganizations = tmOrganizationMapper.selectList(qw);
        double i = tmOrganizations.size();
        qw.eq("org_status",0);
        tmOrganizations=tmOrganizationMapper.selectList(qw);
        double j = tmOrganizations.size();
        double z = i/j;
        int n = (int) Math.ceil(z);
        return String.valueOf(n);
    }

    /**
     * @description 根据阵营找人员
     * @param orgCamp
     * @return
     */
    @Override
    public List<TmPersonnel> getPersonByOrgCamp(String orgCamp) {
        QueryWrapper<TmPersonnel> qw = new QueryWrapper<>();
        if (orgCamp.toUpperCase().equals("CN")){
            qw.eq("personnel_camp",orgCamp);
        }else {
            qw.ne("personnel_camp","CN");
        }
        List<TmPersonnel> tmPersonnelList = tmPersonnelMapper.selectList(qw);
        return tmPersonnelList;
    }

    /**
     * @description 根据阵营找资源
     * @param orgCamp
     * @return
     */
    @Override
    public List<TmAssets> getAssetsByOrgCamp(String orgCamp) {
        QueryWrapper<TmAssets> qw = new QueryWrapper<>();
        if (orgCamp.toUpperCase().equals("CN")){
            qw.eq("assets_camp",orgCamp);
        }else {
            qw.ne("assets_camp","CN");
        }
        List<TmAssets> tmAssets = tmAssetsMapper.selectList(qw);
        return tmAssets;
    }

    /**
     * @description Toolkit集合
     * @param orgCamp
     * @return
     */
    @Override
    public List<TmToolkit> getToolkitByOrgCamp(String orgCamp) {
        QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
        QueryWrapper<TmToolkit> qw1 = new QueryWrapper<>();
        List<String> idlist = new ArrayList<>();
        if (orgCamp.toUpperCase().equals("CN")) {
            qw.eq("org_camp", orgCamp);
        } else {
            qw.ne("org_camp", "CN");
        }
        List<TmOrganization> tmOrganizations = tmOrganizationMapper.selectList(qw);
        for (TmOrganization t:tmOrganizations){
            idlist.add(t.getOrgId());
        }
        qw1.in("id",idlist);
        List<TmToolkit> tmToolkits = tmToolkitMapper.selectList(qw1);
        return tmToolkits;
    }

    /**
     * @description 获取当日新增漏洞
     * @param orgCamp
     * @return
     */
    @Override
    public List<TmLoophole> getNewLoopHoleByOrgCamp(String orgCamp) {
        QueryWrapper<TmLoophole> qw = new QueryWrapper<>();
        if (orgCamp.toUpperCase().equals("CN")) {
            qw.eq("org_camp", orgCamp);
        } else {
            qw.ne("org_camp", "CN");
        }
        qw.ge("create_time", LocalDate.now());
        List<TmLoophole> tmLoopholes = tmLoopholeMapper.selectList(qw);
        return tmLoopholes;
    }

    /**
     * @description 推送6格数据
     * @param orgCamp
     * @return
     */
    @Override
    public String getOverViewByOrgCamp(String orgCamp) {
        Integer tmAsset = getAssetsByOrgCamp(orgCamp).size();
        Integer tmPerson = getPersonByOrgCamp(orgCamp).size();
        Integer tmLoopHole = getLoopHoleByOrgCamp(orgCamp).size();
        Integer tmOrganization = getOrganizationsByOrgCamp(orgCamp).size();
        Integer tmToolIt = getToolkitByOrgCamp(orgCamp).size();
        Integer nLoopHolePercent = getNewLoopHoleByOrgCamp(orgCamp).size();
        List<Integer> overView = new ArrayList<>();
        overView.add(tmAsset);
        overView.add(tmPerson);
        overView.add(tmLoopHole);
        overView.add(tmOrganization);
        overView.add(tmToolIt);
        overView.add(nLoopHolePercent);
        return JSON.toJSONString(overView);
    }

    /**
     * @description 删除
     * @param str
     */
    @Override
    public void deleteDatas(String str){
        JSONArray json = JSONArray.parseArray(str);
        for (int i = 0; i < json.size(); i++) {
           JSONObject jsonObject = (JSONObject) json.get(i);
           if (jsonObject.get("EDGE")==null){
               QueryWrapper<TmOrganization> qw = new QueryWrapper();
               String id = jsonObject.get("Node").toString();
               qw.eq("org_id",id).or().eq("id",id);
                //todo:delete
               tmOrganizationMapper.delete(qw);
               QueryWrapper<TmToolkit> qw1 = new QueryWrapper<>();
               qw1.eq("org_id",id);
               tmToolkitMapper.delete(qw1);
           }else {
               JSONObject jsonObject1 = (JSONObject) jsonObject.get("EDGE");
               QueryWrapper<TmEdge> qw1 = new QueryWrapper<>();
               qw1.eq("from_id",jsonObject1.get("fromId").toString());
               qw1.eq("to_id",jsonObject1.get("toId").toString());
               //todo:delete
               tmEdgeMapper.delete(qw1);
           }
        }
    }

    @Override
    public synchronized void addDatas(String jsonString) {
        JSONObject jsonObject = (JSONObject) JSONObject.parse(jsonString);
        System.out.println(jsonObject);
        if (jsonObject.get("node")!=null){
            //点
            JSONObject jsonObject1 = (JSONObject) jsonObject.get("node");
            QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
            String org_id = jsonObject1.get("id").toString();
            String orgType = jsonObject1.get("orgType").toString();
            qw.eq("id",org_id);
            qw.eq("org_type",orgType);
            Integer integer = tmOrganizationMapper.selectCount(qw);
            if (integer==0){
                TmOrganization organization = new TmOrganization();
                organization.setOrgType(orgType);
                organization.setOrgId(org_id);
                //organization.setId(UUID.randomUUID().toString().replace("-",""));
                organization.setId(org_id);
                organization.setOrgCamp("unknown");
                organization.setCreateTime(new Timestamp(new Date().getTime()));
                if (orgType.equals("1")){
                    organization.setOrgName("Mac");
                }else if (orgType.equals("2")){
                    organization.setOrgName("Ex-Changer");
                }else{
                    organization.setOrgName("Server");
                }
                organization.setOrgStatus("1");
                organization.setOrgMierarchy("0");
                //todo：insert
                tmOrganizationMapper.insert(organization);
            }
        }else {
            //线
            JSONObject jsonObject1 = (JSONObject) jsonObject.get("EDGE");
            String toId = jsonObject1.get("toId").toString();
            String fromId = jsonObject1.get("fromId").toString();
            String edgeType = jsonObject1.get("edgType").toString();
            QueryWrapper<TmEdge> eqw =new QueryWrapper<>();
            eqw.eq("from_id",fromId);
            eqw.eq("to_id",toId);
            eqw.eq("edge_type",edgeType);
            Integer integer = tmEdgeMapper.selectCount(eqw);
            //全部做完了插入线
            if (integer==0) {//不存在插入 存在啥也不干
                TmEdge edge = new TmEdge();
                edge.setToId(toId);
                edge.setFromId(fromId);
                boolean f=aa(edge);
                edge.setEdgType(edgeType);
                edge.setCreateTime(new Timestamp(new Date().getTime()));
                edge.setId(UUID.randomUUID().toString().replace("-", ""));
                if (f){
                    tmEdgeMapper.insert(edge);
                }
            }
        }
    }

    /**
     * @description 地图数据填充 名字是descr 直接将descr 的kmap传到前台去json中解析
     * @return
     */
    @Override
    public String getChinaMapData() {
        QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
        qw.eq("org_camp","CN");
        List<TmOrganization> tmOrganizations = tmOrganizationMapper.selectList(qw);
        Map<String,String> chinaMap = new HashMap<>();
        List<TmEdge> edgeList = new ArrayList<>();
        //点 list集合
        for (TmOrganization t: tmOrganizations) {
            chinaMap.put(t.getOrgId(),t.getOrgDescr());//将ID-描述 存key后面用
        }
        //线 Edge List
        for (TmOrganization t: tmOrganizations) {
            {
                TmEdge edge = new TmEdge();
                edge.setFromId(chinaMap.get(t.getParentId()));//from
                edge.setToId(chinaMap.get(t.getOrgId())); //to
                edgeList.add(edge);
            }
        }
        Map<String,Object> data =new HashMap<>();
        data.put("node",tmOrganizations);
        data.put("edge",edgeList);
        System.out.println(JSON.toJSONString(data));
        return JSON.toJSONString(data);
    }

    public boolean aa(TmEdge edge){
        QueryWrapper<TmOrganization> qw = new QueryWrapper<>();
        String toId = edge.getToId();
        String fromId = edge.getFromId();
        QueryWrapper<TmEdge> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("to_id",toId);
        Integer integer = tmEdgeMapper.selectCount(queryWrapper);
        if (integer==0){
            //分类考虑改变点的关系
            qw.eq("id",fromId);
            TmOrganization one = tmOrganizationMapper.selectOne(qw);
            qw.clear();
            qw.eq("id",toId);
            TmOrganization two = tmOrganizationMapper.selectOne(qw);
            List<TmOrganization> campList = new ArrayList<>();
            campList.add(one);
            campList.add(two);
            //判断unknown
            String camp1 =one.getOrgCamp();
            String camp2 =two.getOrgCamp();
            //todo：直接插入 改变层级
            if (camp1.equals(camp2)) {//相同
                qw.clear();
                qw.eq("id",fromId);//高层级
                TmOrganization organization = tmOrganizationMapper.selectOne(qw);
                qw.clear();
                UpdateWrapper<TmOrganization> org = new UpdateWrapper<>();
                org.eq("id",toId).set("org_mierarchy",Integer.valueOf(organization.getOrgMierarchy())+1)
                        .set("parent_id",fromId)
                        .set("update_time",new Date());
                tmOrganizationMapper.update(null,org);
            }else{
                if (camp1.equals("unknown")||camp2.equals("unknown")){
                    //不同且有一个unknown
                    UpdateWrapper<TmOrganization> org = new UpdateWrapper<>();
                    org.eq("id",toId)
                            .set("org_mierarchy",String.valueOf(Integer.valueOf(campList.get(0).getOrgMierarchy())+1))
                            .set("parent_id",fromId)
                            .set("org_camp",campList.get(0).getOrgCamp())
                            .set("update_time",new Date());
                    int update = tmOrganizationMapper.update(null, org);
                    if(update>0){
                        toUpdate(tmOrganizationMapper.selectById(toId),campList.get(0).getOrgCamp());
                    }
                }
                //不同且都不是unknown 啥都不干
            }
            return true;
        }
        return false;
    }

    /**
     * 递归改变阵营
     * @param org
     */
    private void toUpdate(TmOrganization org,String orgCamp) {
        QueryWrapper<TmOrganization> qw = new QueryWrapper();
        qw.eq("parent_id",org.getOrgId());
        List<TmOrganization> organizationList = tmOrganizationMapper.selectList(qw);
        for (TmOrganization o :organizationList) {
            UpdateWrapper<TmOrganization> uw = new UpdateWrapper<>();
            uw.eq("id",o.getId())
                    .set("org_mierarchy",String.valueOf(Integer.valueOf(org.getOrgMierarchy())+1))
                    .set("org_camp",orgCamp)
                    .set("update_time",new Date());
            int update = tmOrganizationMapper.update(null, uw);
            if(update>0){
                toUpdate(o,orgCamp);
            }
        }
    }

    @Override
    public List<TmLoophole> selectTmLoophole() {
        QueryWrapper<TmLoophole> qw = new QueryWrapper();
        List<TmLoophole> organizationList = tmLoopholeMapper.selectList(qw);
        return organizationList;
    }

    @Override
    public List<TmAssets> selectTmAssets() {
        QueryWrapper<TmAssets> qw = new QueryWrapper();
        List<TmAssets> organizationList = tmAssetsMapper.selectList(qw);
        return organizationList;
    }

    @Override
    public List<TmToolkit> selectTmToolkit() {
        QueryWrapper<TmToolkit> qw = new QueryWrapper();
        List<TmToolkit> organizationList = tmToolkitMapper.selectList(qw);
        return organizationList;
    }
}
